package com.joejag.mavenstats.server.reports.impls;

import com.joejag.mavenstats.client.dto.ReportDTO;
import com.joejag.mavenstats.server.dao.ProjectsDao;
import static com.joejag.mavenstats.server.reports.CommonReportUtils.getOccurancesMapOfDependenciesByGrouping;
import com.joejag.mavenstats.server.reports.JFreechartable;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class MostUsedDependenciesByGroupingReport implements JFreechartable
{
  private static final int NUMBER_TO_SHOW = 10;
  
  private ProjectsDao projectsDao;

  public MostUsedDependenciesByGroupingReport(ProjectsDao projectsDao)
  {
    this.projectsDao = projectsDao;
  }

  public JFreeChart getJFreeChart()
  {
    List<ReportModel> reportModelList = getTop10(transmogrify(getOccurancesMapOfDependenciesByGrouping(projectsDao)));

    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    for (ReportModel reportModel : reportModelList)
      dataset.setValue(reportModel.occurances, reportModel.grouping, "");

    return ChartFactory.createBarChart(getReportName(), "Grouping", "Projects Usage", dataset, PlotOrientation.VERTICAL, true, false, false);
  }

  public ReportDTO generateReport()
  {
    List<ReportModel> reportModelList = getTop10(transmogrify(getOccurancesMapOfDependenciesByGrouping(projectsDao)));

    String body = "<ul>";
    for (ReportModel reportModel : reportModelList)
      body += "<li>" + reportModel.grouping + " :: " + reportModel.occurances + "</li>";
    body += "</ul>";

    return new ReportDTO(getReportName(), body);
  }

  private List<ReportModel> transmogrify(Map<String, Integer> result)
  {
    List<ReportModel> list = new ArrayList<ReportModel>();

    for (String grouping : result.keySet())
      list.add(new ReportModel(grouping, result.get(grouping)));

    return list;
  }

  private List<ReportModel> getTop10(List<ReportModel> reportModelList)
  {
    Collections.sort(reportModelList);
    Collections.reverse(reportModelList);

    if (reportModelList.size() < NUMBER_TO_SHOW)
      return reportModelList;

    return reportModelList.subList(0, NUMBER_TO_SHOW);
  }

  public String getReportName()
  {
    return "Most Used Dependencies - By Grouping";
  }

  private class ReportModel implements Comparable
  {
    public String grouping;
    public int occurances;

    private ReportModel(String grouping, int occurances)
    {
      this.grouping = grouping;
      this.occurances = occurances;
    }

    public int compareTo(Object o)
    {
      ReportModel other = (ReportModel) o;
      return this.occurances - other.occurances;
    }
  }
}
